/*
*	Project: Aethon
*
*	File: Model.cpp
*
*	Author: Robert Whiting
*
*	Date: 2/11/2009
*
*	Purpose: The model contains information for objects within the scene,
*	including physical attributes, physics attributes, and the model part
*	root item
*/

#include "../include/Model.h"

void Model::display(void){
	update();
	glPushMatrix();
    glTranslatef(position.v[0],position.v[1],-position.v[2]);
	//set to negative z so it moves same way as eye handler does
    glRotatef(direction.v[0]*9.11,0,0,1);
    glRotatef(direction.v[1]*9.11,0,1,0);
    glRotatef(direction.v[2]*9.11,1,0,0);
    if(hasVisibility){
		rootModelPart.display();
	}
	if(collisionSphere.getHasVisibility()){
		collisionSphere.display();
	}
    glPopMatrix();
}//end display

void Model::update(void){
	//fprintf(stderr,"Model::update\n");
	frame currentFrame = animator.update();
	for(int i=0; i<(int)currentFrame.relativeRotations.size(); i++){
		//fprintf(stderr,"\t%s %.2f %.2f %.2f\n",currentFrame.names[i].c_str(),currentFrame.relativeRotations[i].v[0],currentFrame.relativeRotations[i].v[1],currentFrame.relativeRotations[i].v[2]);
		applyRelativeRotationByName(currentFrame.names[i],currentFrame.relativeRotations[i]);
	}
}//end update

void Model::load(string filename){
	//fprintf(stderr,"Model::load '%s'\n", filename.c_str());
	setName(filename);
	filename = "../data/models/" + filename + ".m";
	ifstream inData;
	inData.open(filename.c_str());
	string token;
    if(!inData){
    	fprintf(stderr,"Data file failed: '%s'\n",filename.c_str());
    	exit(1);
    }
    char comment = inData.peek();
    //read all comments
    while(comment == '#'){
		inData.ignore(100,'\n');
		comment = inData.peek();
    }
	//gravity, visability, collisionSphereRadius
	float collisionSphereRadius;
	inData >> hasGravity >> hasVisibility >> collisionSphereRadius;
	collisionSphere.setRadius(collisionSphereRadius);
    //position
    float pos[3];
	inData >> pos[0] >> pos[1] >> pos[2];
	position = vector3f(pos);
	collisionSphere.setHasVisibility(false);
	collisionSphere.setCenterPosition(position);
	collisionSphere.setRelativePosition(vector3f(0,0,0));
	//direction
	float dir[3];
	inData >> dir[0] >> dir[1] >> dir[2];
	dir[0] = dir[0]/9.11;
	dir[1] = dir[1]/9.11;
	dir[2] = dir[2]/9.11;
	direction = vector3f(dir);
	//velocity
	float vel[3];
	inData >> vel[0] >> vel[1] >> vel[2];
	velocity = vector3f(vel);
	//modelPartFilename name
	string modelPartFilename = "";
	inData >> modelPartFilename;
	//fprintf(stderr, "filename read in\n");
	rootModelPart.load(modelPartFilename);
    inData.close();
    
	fprintf(stderr, "Loading Animator\n");
    animator.init();
	printf("Loading '%s' complete\n", filename.c_str());
}//end load

//#######################################################
void Model::applyRelativeRotationByName(string name, vector3f rotation){
	rootModelPart.applyRelativeRotationByName(name, rotation);
}//end applyRelativeRotationByName

//#######################################################
void Model::printFrame(float time){
	ofstream outFile;
	outFile.open("frames.txt", ios::out | ios::app);
	outFile << "f " << time;
    outFile.close();
	rootModelPart.printFrame();
	outFile.open("frames.txt", ios::out | ios::app);
    outFile << "\n";
    outFile.close();
}//end printFrame

//#######################################################
void Model::interruptMovement(string movementName){
	animator.interruptMovement(movementName);
}//end interruptMovement

//#######################################################
void Model::pushMovement(string movementName){
	animator.pushMovement(movementName);
}//end pushMovement


